package com.wing.sell.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wing.common.enums.MaintenanceEnum;
import com.wing.common.enums.ProductEnum;
import com.wing.common.utils.CodeUtil;
import com.wing.common.utils.UniqueIdGeneratorUtil;
import com.wing.product.model.entity.ProductType;
import com.wing.product.model.entity.ProductUnitInfo;
import com.wing.product.service.DynamicService;
import com.wing.product.service.ProductTypeService;
import com.wing.product.service.ProductUnitService;
import com.wing.res.model.entity.ReceiptRecord;
import com.wing.res.model.entity.ReceiptRecordDetail;
import com.wing.res.service.ReceiptRecordDetailService;
import com.wing.res.service.ReceiptRecordService;
import com.wing.sell.dao.DeliveryPlanDao;
import com.wing.sell.dao.OrderDao;
import com.wing.sell.model.entity.*;
import com.wing.sell.model.request.DeliveryRecordForm;
import com.wing.sell.model.request.OrderForm;
import com.wing.sell.model.request.OrderFormalForm;
import com.wing.sell.model.response.OrderSkuDetailSearchVo;
import com.wing.sell.model.response.OrderVO;
import com.wing.sell.service.*;
import com.wing.sell.strategy.SelOrder;
import com.wing.web.utils.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;

/**
 * 销售订单表-ServiceImpl
 *
 * @author
 */
@Service
@Slf4j
public class OrderServiceImpl extends ServiceImpl<OrderDao, Order> implements OrderService {

    @Autowired
    private DynamicService dynamicService;
    @Autowired
    private OrderProService orderProService;

    @Autowired
    private OrderOfferService orderOfferService;

    @Autowired
    private OrderOfferDetailService orderOfferDetailService;

    @Autowired
    private OrderProEnclosureService orderProEnclosureService;
    @Autowired
    private CustomersInfoService customersInfoService;

    @Autowired
    private DeliveryPlanDao deliveryPlanDao;

    @Autowired
    private DeliveryRecordService deliveryRecordService;

    @Autowired
    private ReceiptRecordService receiptRecordService;

    @Autowired
    private ReceiptRecordDetailService receiptRecordDetailService;

    @Autowired
    private DeliveryRecordDetailService deliveryRecordDetailService;

    @Autowired
    private ProductUnitService productUnitService;

    @Autowired
    private ProductTypeService productTypeService;

    @Override
    public void add(OrderForm orderForm) {

        //校验

        Order order =new Order();
        CopyOptions copyOptions = CopyOptions.create()
        .setEditable(Order.class)
        .setIgnoreError(true)
        .setIgnoreNullValue(true);
        BeanUtil.copyProperties(orderForm, order, copyOptions);
        //刚添加为待提交状态
        order.setStatus(Order.Status.pending);
        SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyyMMdd");
        String code=dynamicService.getDayNextCode("sel_order");
        String day=simpleDateFormat.format(new Date());
        order.setCode("DD"+day+code);
        order.setDay(Integer.valueOf(day));
        order.setNo(Integer.valueOf(code));
        order.setProQuantity(orderForm.getOrderProList().size());
        order.setOrderRoot(Order.OrderRoot.enquiry);
        baseMapper.insert(order);
        //保存产品
        for (OrderPro orderPro:orderForm.getOrderProList()){
            //刚添加为待受理状态
            orderPro.setOrderId(order.getId());
            orderPro.setStatus(OrderPro.Status.pending);
            //刚添加终审结果为未处理 默认值
            orderPro.setFinalResult(OrderPro.FinalResult.unhandled);
            orderPro.setSelRemainQuality(Long.valueOf(orderPro.getQuantity()));
            orderProService.getBaseMapper().insert(orderPro);
            for (OrderProEnclosure orderProEnclosure:orderPro.getOrderProEnclosureList()){
                orderProEnclosure.setOrderId(order.getId());
                orderProEnclosure.setProId(orderPro.getId());
                orderProEnclosureService.getBaseMapper().insert(orderProEnclosure);
            }
        }

    }

    @Override
    public List<OrderVO> list4app(Map<String, Object> params) {
        return baseMapper.list4app(params);
    }

    @Override
    public Page<OrderVO> pageList4app(Page page, Map<String, Object> params) {
        List<OrderVO> list = baseMapper.list4app(page, params);
        page.setRecords(list);
        return page;
    }

    @Override
    public OrderVO get4appById(Long id) {
        return baseMapper.get4appById(id);
    }

    @Override
    public void submit(Long id,Integer type) {
        OrderVO orderVO= baseMapper.get4appById(id);
        Order order =new Order();
        CopyOptions copyOptions = CopyOptions.create()
                .setEditable(Order.class)
                .setIgnoreError(true)
                .setIgnoreNullValue(true);
        BeanUtil.copyProperties(orderVO, order, copyOptions);
        if(type==1){
            order.setStatus(Order.Status.accept);
        }else if (type==2){
            order.setStatus(Order.Status.review);
            //产品数量修改为 只计算受理的产品
            order.setProQuantity(orderProService.list(new QueryWrapper<OrderPro>().eq("order_id",id).eq("status",OrderPro.Status.accepted)).size());
        }else if (type==8){
            order.setStatus(Order.Status.over);
        }else if (type==7){
            order.setStatus(Order.Status.finish);
        }else if (type==4){
            order.setStatus(Order.Status.offer);
            //产品数量修改为 只计算终审通过的产品
            order.setProQuantity(orderProService.list(new QueryWrapper<OrderPro>().eq("order_id",id).eq("final_result",OrderPro.FinalResult.pass)).size());
        }else if (type==3){
            //所有产品都不接单 订单状态修改为不接单
            order.setStatus(Order.Status.refuse);
        }else if (type==6){
            //绑定的合同为已签约或者合同设为终版时
            order.setStatus(Order.Status.signed);
            //如果是意向客户  不是正是用户 改为正式用户
            CustomersInfo customersInfo =  customersInfoService.getBaseMapper().selectById(order.getCustomerId());
            if (customersInfo.getCustomerType()!=CustomersInfo.CustomerType.formal){
                customersInfo.setCustomerType(CustomersInfo.CustomerType.formal);
                customersInfoService.updateById(customersInfo);
            }
        }
        baseMapper.updateById(order);
    }

    //添加正式订单
    @Override
    public void addFormal(OrderForm orderForm) {
        Order order =new Order();
        CopyOptions copyOptions = CopyOptions.create()
                .setEditable(Order.class)
                .setIgnoreError(true)
                .setIgnoreNullValue(true);
        BeanUtil.copyProperties(orderForm, order, copyOptions);
        order.setStatus(Order.Status.signed);//刚添加为已签约状态
        SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyyMMdd");
        String code=dynamicService.getDayNextCode("sel_order");
        String day=simpleDateFormat.format(new Date());
        order.setCode("DD"+day+code);
        order.setDay(Integer.valueOf(day));
        order.setNo(Integer.valueOf(code));
        order.setPcStatus(MaintenanceEnum.pcStatusEmum.DPC.getCode());
        order.setProQuantity(orderForm.getOrderProList().size());
        order.setOrderRoot(Order.OrderRoot.formal);
        baseMapper.insert(order);
        //保存产品
        for (OrderPro orderPro:orderForm.getOrderProList()){
            orderPro.setOrderId(order.getId());
            orderPro.setStatus(OrderPro.Status.accepted);//刚添加为已受理状态
            orderPro.setFinalResult(OrderPro.FinalResult.pass);//刚添加终审结果为接单 默认值
            orderPro.setOfferStatus(OrderPro.OfferStatus.wait);//刚添加报价状态为待报价 默认值
            orderProService.getBaseMapper().insert(orderPro);
            for (OrderProEnclosure orderProEnclosure:orderPro.getOrderProEnclosureList()){
                orderProEnclosure.setOrderId(order.getId());
                orderProEnclosure.setProId(orderPro.getId());
                orderProEnclosureService.getBaseMapper().insert(orderProEnclosure);
            }
        }
    }

    /**
     * 查询订单详情
     *
     * @param id
     * @return
     */
    @Override
    public OrderVO getDetailById(Long id) {
        return baseMapper.getDetailById(id);
    }

    /**
     * 查询订单中物料信息
     * @param orderId
     * @param warehouseId
     * @return
     */
    @Override
    public List<OrderSkuDetailSearchVo> listByInfo(Long orderId, Long warehouseId) {
        List<OrderSkuDetailSearchVo> searchVos = baseMapper.listByInfo(orderId,warehouseId);
        for (OrderSkuDetailSearchVo searchVo : searchVos) {
            BigDecimal offMoneyByProductDetailId = this.orderOfferService.getOffMoneyByProductDetailId(orderId, searchVo.getProductDetailId());
            if (offMoneyByProductDetailId!=null){
                searchVo.setCurrentCostPrice(offMoneyByProductDetailId);
            }
        }

        return searchVos;
    }


    /**
     * 生成交付记录
     * @param deliveryRecordForm
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer generateOrderResult(DeliveryRecordForm deliveryRecordForm) {
        //校验
        DeliveryRecord deliveryRecord = new DeliveryRecord();
        //交付记录编号
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
        //getDayMaxNo
        String today = format.format(new Date());
        Integer maxCode = deliveryPlanDao.getDayMaxNo("sel_delivery_record");
        String maxNo = CodeUtil.getCode(maxCode);
        String code = today + maxNo;
        CopyOptions copyOptions = CopyOptions.create().setEditable(DeliveryRecord.class).setIgnoreError(true).setIgnoreNullValue(true);
        BeanUtil.copyProperties(deliveryRecordForm, deliveryRecord, copyOptions);
        deliveryRecord.setRecordCode(code);
        deliveryRecord.setNo(Integer.valueOf(maxNo));
        deliveryRecord.setSaleOrderCode(deliveryRecordForm.getSaleOrderCode());
        deliveryRecord.setDay(Integer.valueOf(today));
        boolean save = deliveryRecordService.save(deliveryRecord);
        if (!save) {
            return 0;
        }
        //交付记录id
        ReceiptRecord receiptRecord = ReceiptRecord.builder()
                .auditPerson(JwtUtils.getLoginUserId())
                .auditPersonName(JwtUtils.getLoginUsername())
                //出库已审核
                .auditResult("2")
                .creator(JwtUtils.getLoginUserId())
                .createTime(new Date())
                .creatorName(JwtUtils.getLoginUsername())
                .inventoryTypeId(deliveryRecordForm.getTypeId())
                //放入交付记录id
                .workOrderId(deliveryRecord.getId())
                .warehouseType(deliveryRecordForm.getWarehouseTypeId())
                .receiptWarehouse(deliveryRecordForm.getWarehouseId())
                .build();
        String taskNo = UniqueIdGeneratorUtil.generateUniqueId("LL", "yyyyMMdd", 1000, 9999);
        receiptRecord.setCode(taskNo);
        //待审核
        receiptRecord.setStatus(2);
        receiptRecord.setRemark("生产发货物流记录自动生成");
        this.receiptRecordService.save(receiptRecord);
        //成品销售逻辑
        if (CollectionUtil.isNotEmpty(deliveryRecordForm.getDeliveryRecordDetails())) {
            //交付记录列表
            List<DeliveryRecordDetail> recordDetailList = new ArrayList<>();
            //批量修改的库存列表
            List<OrderPro> orderPros = new ArrayList<>();
            //仓库物料相关列表
            List<ReceiptRecordDetail> receiptRecordDetails = new ArrayList<>();

            for (DeliveryRecordDetail deliveryRecordDetail : deliveryRecordForm.getDeliveryRecordDetails()) {
                deliveryRecordDetail.setSkuId(deliveryRecordDetail.getProductDetailId());
                deliveryRecordDetail.setUnitId(deliveryRecordDetail.getMainUnitId());
                deliveryRecordDetail.setUnitName(deliveryRecordDetail.getMainUnitName());
                deliveryRecordDetail.setProductName(deliveryRecordDetail.getSkuName());
                deliveryRecordDetail.setSubtotalAmount(deliveryRecordDetail.getSubtotalAmount());
                Long selRemainQuality = deliveryRecordDetail.getSelRemainQuality();
                //上次剩余
                Long lastQuality = null;
                if (null != selRemainQuality && !selRemainQuality.equals(0L)) {
                    //得到此次剩余
                    lastQuality = selRemainQuality - deliveryRecordDetail.getShipmentQty();
                    deliveryRecordDetail.setSurplus(lastQuality);
                }
                deliveryRecordDetail.setDeliveryRecordId(deliveryRecord.getId());
                //交付情况:0-未交付，1-交付有剩余，2-交付完成
                if (null != lastQuality && lastQuality > 0L) {
                    deliveryRecordDetail.setDeliverySituation(ProductEnum.deliverySituationEmum.JFYSY.getCode());
                } else if (null != lastQuality && lastQuality == 0L) {
                    deliveryRecordDetail.setDeliverySituation(ProductEnum.deliverySituationEmum.JFWC.getCode());
                } else {
                    deliveryRecordDetail.setDeliverySituation(ProductEnum.deliverySituationEmum.WJF.getCode());
                }
                //保存记录
                recordDetailList.add(deliveryRecordDetail);
                //修改对应订单状态 以及剩余库存
                QueryWrapper<OrderPro> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("id", deliveryRecordDetail.getOrderDetailId());
                queryWrapper.eq("order_id", deliveryRecord.getSaleOrderId());
                OrderPro one = this.orderProService.getOne(queryWrapper);
                one.setSelRemainQuality(lastQuality);
                one.setUpdateTime(LocalDateTime.now());
                one.setModifier(JwtUtils.getLoginUserId());
                one.setModifierName(JwtUtils.getLoginUsername());
                orderPros.add(one);

                ReceiptRecordDetail receiptRecordDetail = new ReceiptRecordDetail();
                receiptRecordDetail.setReceiptRecordId(receiptRecord.getId());
                receiptRecordDetail.setProductDetailId(deliveryRecordDetail.getProductDetailId());
                receiptRecordDetail.setReceiptNum(new BigDecimal(deliveryRecordDetail.getShipmentQty()));
                receiptRecordDetail.setRemark("成品发货物流记录自动生成");
                receiptRecordDetail.setCreateTime(new Date());
                receiptRecordDetails.add(receiptRecordDetail);
            }
            //批量修改
            this.deliveryRecordDetailService.saveBatch(recordDetailList);
            this.receiptRecordDetailService.saveBatch(receiptRecordDetails);
            this.orderProService.updateBatchById(orderPros);
            return 1;
        }
        return 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addFormalOrder(OrderFormalForm orderFormalForm) {
        //1.订单信息
        Order order =new Order();
        CopyOptions copyOptions = CopyOptions.create()
                .setEditable(Order.class)
                .setIgnoreError(true)
                .setIgnoreNullValue(true);
        BeanUtil.copyProperties(orderFormalForm, order, copyOptions);
        //刚添加为已签约状态
        order.setStatus(Order.Status.finish);
        SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyyMMdd");
        String code=dynamicService.getDayNextCode("sel_order");
        String day=simpleDateFormat.format(new Date());
        order.setCode("DD"+day+code);
        order.setDay(Integer.valueOf(day));
        order.setNo(Integer.valueOf(code));
        order.setOrderType(Order.OrderType.mass);
        order.setProQuantity(orderFormalForm.getOrderProList().size());
        order.setAmount(orderFormalForm.getAmount());
        order.setCreator(JwtUtils.getLoginUserId());
        order.setPcStatus(MaintenanceEnum.pcStatusEmum.DPC.getCode());
        order.setCreatorName(JwtUtils.getLoginUsername());
        order.setCreateTime(LocalDateTime.now());

        order.setOrderRoot(Order.OrderRoot.formal);
        baseMapper.insert(order);

        //2. 生成报价详情
        List<OrderOfferDetail> details = new ArrayList<>();
        //自动生成一条报价的信息
        OrderOffer orderOffer = new OrderOffer();
        orderOffer.setOrderId(order.getId());
        String code2=dynamicService.getDayNextCode("sel_order_offer");
        orderOffer.setCode("BJ"+day+code);
        orderOffer.setDay(Integer.valueOf(day));
        orderOffer.setNo(Integer.valueOf(code2));
        orderOffer.setUpdateDuring("0");
        orderOffer.setRemark("手动添加正式订单 自动填充!");
        orderOffer.setWhetherFinal(true);
        orderOffer.setCreator(JwtUtils.getLoginUserId());
        orderOffer.setCreatorName(JwtUtils.getLoginUsername());
        orderOffer.setCreateTime(LocalDateTime.now());
        orderOffer.setProNum(orderFormalForm.getOrderProList().size());
        this.orderOfferService.save(orderOffer);

        //保存订单产品
        for (OrderPro orderPro:orderFormalForm.getOrderProList()){
            //设置报价信息
            orderPro.setOrderId(order.getId());
            //刚添加为已受理状态
            orderPro.setStatus(OrderPro.Status.accepted);
            //刚添加终审结果为接单 默认值
            orderPro.setFinalResult(OrderPro.FinalResult.pass);
            //刚添加报价状态为待报价 默认值
            orderPro.setOfferStatus(OrderPro.OfferStatus.finish);
            orderPro.setCreator(JwtUtils.getLoginUserId());
            orderPro.setCreatorName(JwtUtils.getLoginUsername());
            orderPro.setSelRemainQuality(Long.valueOf(orderPro.getQuantity()));
            orderPro.setCreateTime(LocalDateTime.now());
            orderProService.getBaseMapper().insert(orderPro);

            //3. 报价详情
            OrderOfferDetail orderOfferDetail = new OrderOfferDetail();
            orderOfferDetail.setOrderId(order.getId());
            orderOfferDetail.setProId(orderPro.getId());
            orderOfferDetail.setOfferId(orderOffer.getId());
            orderOfferDetail.setOfferMoney(orderPro.getOfferMoney());
            orderOfferDetail.setCreator(JwtUtils.getLoginUserId());
            orderOfferDetail.setCreatorName(JwtUtils.getLoginUsername());
            orderOfferDetail.setCreateTime(LocalDateTime.now());
            orderOfferDetail.setLastMoney(orderPro.getOfferMoney());
            orderOfferDetail.setProductDetailId(orderPro.getProductDetailId());
            details.add(orderOfferDetail);

            //订单附件
            for (OrderProEnclosure orderProEnclosure:orderPro.getOrderProEnclosureList()){
                orderProEnclosure.setOrderId(order.getId());
                orderProEnclosure.setProId(orderPro.getId());
                orderProEnclosure.setCreator(JwtUtils.getLoginUserId());
                orderProEnclosure.setCreatorName(JwtUtils.getLoginUsername());
                orderProEnclosure.setCreateTime(LocalDateTime.now());
                orderProEnclosureService.getBaseMapper().insert(orderProEnclosure);
            }
        }

        // 保存报价详情
        this.orderOfferDetailService.saveBatch(details);
    }

    /**
     * 查询订单的物料详情
     * @param orderId 订单id
     * @return
     */
    @Override
    public List<OrderSkuDetailSearchVo> listByInfoBySku(Long orderId) {
        List<OrderSkuDetailSearchVo> searchVos = this.baseMapper.listByInfoBySku(orderId);
        //查询所有的单位
        List<ProductUnitInfo> infoList = productUnitService.list();

        //查询所有的类型信息
        List<ProductType> list = productTypeService.listAndSelectBaseUnit();

        searchVos.forEach(vo -> {
            for (ProductUnitInfo productUnitInfo : infoList) {
                if (productUnitInfo.getId().equals(vo.getMainUnitId())) {
                    vo.setMainUnitName(productUnitInfo.getName());
                }
            }

            for (ProductType productType : list) {
                if (productType.getId().equals(vo.getProductTypeId())) {
                    vo.setProductTypeName(productType.getName());
                    vo.setBaseUnitId(productType.getBaseUnitId());
                    vo.setBaseUnitName(productType.getBaseUnitName());
                }
            }
        });
        return searchVos;
    }

}
